﻿using System;
using System.ComponentModel.DataAnnotations;
using System.Text;
using Dgg.Anug.Cqrs.Core.Application.Admin.Commands;
using Dgg.Anug.Cqrs.Core.Infrastructure.Validation;
using NUnit.Framework;

namespace Dgg.Anug.Cqrs.Core.Tests.Infrastructure.Validation
{
	[TestFixture]
	public class CreateBulkOfBuildsValidationTester
	{
		[Test]
		public void Null_Invalid()
		{
			ValidationService subject = new ValidationService();
			CreateBulkOfBuilds @null = null;
			Assert.That(() => subject.AssertValidity(@null), Throws.InstanceOf<ArgumentNullException>());
		}

		[Test]
		public void AllPropertiesValid_Valid()
		{
			ValidationService subject = new ValidationService();
			CreateBulkOfBuilds valid = new CreateBulkOfBuilds("pre", 0, 5) { Suffix = "post" };
			Assert.That(() => subject.AssertValidity(valid), Throws.Nothing);
		}

		[Test, Sequential]
		public void MissingMandatoryProperty_Prefix_Invalid(
			[Values(null, "")]string missing)
		{
			ValidationService subject = new ValidationService();
			CreateBulkOfBuilds valid = new CreateBulkOfBuilds(missing, 0, 5) { Suffix = "post" };
			Assert.That(() => subject.AssertValidity(valid), Throws.InstanceOf<ValidationException>());
		}

		[Test]
		public void OverflowProperty_Prefix_Invalid()
		{
			ValidationService subject = new ValidationService();
			CreateBulkOfBuilds valid = new CreateBulkOfBuilds(buildLongString(13), 0, 5) { Suffix = "post" };
			Assert.That(() => subject.AssertValidity(valid), Throws.InstanceOf<ValidationException>());
		}

		[Test, Sequential]
		public void OverflowEdgeCases_RangeStart_Invalid(
			[Values(0, 3000)]
			int edge)
		{
			ValidationService subject = new ValidationService();
			CreateBulkOfBuilds valid = new CreateBulkOfBuilds("pre", edge, 3000) { Suffix = "post" };
			Assert.That(() => subject.AssertValidity(valid), Throws.Nothing);
		}

		[Test, Sequential]
		public void OverflowProperty_RangeStart_Invalid(
			[Values(-1, 3001)]
			int overflowing)
		{
			ValidationService subject = new ValidationService();
			CreateBulkOfBuilds valid = new CreateBulkOfBuilds("pre", overflowing, 5) { Suffix = "post" };
			Assert.That(() => subject.AssertValidity(valid), Throws.InstanceOf<ValidationException>());
		}

		[Test, Sequential]
		public void OverflowEdgeCases_RangeEnd_Invalid(
			[Values(0, 3000)]
			int edge)
		{
			ValidationService subject = new ValidationService();
			CreateBulkOfBuilds valid = new CreateBulkOfBuilds("pre", 0, edge) { Suffix = "post" };
			Assert.That(() => subject.AssertValidity(valid), Throws.Nothing);
		}

		[Test, Sequential]
		public void OverflowProperty_RangeEnd_Invalid(
			[Values(-1, 3001)]
			int overflowing)
		{
			ValidationService subject = new ValidationService();
			CreateBulkOfBuilds valid = new CreateBulkOfBuilds("pre", 0, overflowing) { Suffix = "post" };
			Assert.That(() => subject.AssertValidity(valid), Throws.InstanceOf<ValidationException>());
		}

		[Test]
		public void RangeBoundsUnordered_Invalid()
		{
			ValidationService subject = new ValidationService();
			CreateBulkOfBuilds valid = new CreateBulkOfBuilds("pre", 2, 1) { Suffix = "post" };
			Assert.That(() => subject.AssertValidity(valid), Throws.InstanceOf<ValidationException>());
		}

		private static string buildLongString(uint groupsOfThenChars)
		{
			string oneToZero = "1234567890";
			StringBuilder sb = new StringBuilder((int)(10u * groupsOfThenChars));
			for (uint i = 0; i < groupsOfThenChars; i++)
			{
				sb.Append(oneToZero);
			}
			return sb.ToString();
		}
	}
}